/*
 * AppModule.java July 2009
 *
 * Copyright (C) 2009, Quirino Zagarese <quirino@laszloitalia.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA  02111-1307  USA
 */
package org.eu4ria;

import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Hashtable;

import org.eu4ria.core.HashFunctions;

public class AppModule {

	private Object javaObject;

	private String hash;

	/** The business class. */
	private Class<?> javaClass;

	/** The actions. */
	private Hashtable<String,AppAction> actions = new Hashtable<String, AppAction>();


	private Hashtable<String, String> hashBindings = new Hashtable<String, String>();


	/** The declaring app. */
	private Application declaringApp;


	/**
	 * Gets the declaring app.
	 *
	 * @return the declaring app
	 */
	public Application getDeclaringApp() {
		return declaringApp;
	}

	/**
	 * Sets the declaring app.
	 *
	 * @param declaringApp the new declaring app
	 */
	public void setDeclaringApp(Application declaringApp) {
		this.declaringApp = declaringApp;
	}




	/**
	 * Gets the java class.
	 *
	 * @return the java class
	 */
	public Class getJavaClass() {
		return javaClass;
	}

	/**
	 * Sets the java class.
	 *
	 * @param clazz the new java class
	 */
	public void setJavaClass(Class clazz) {
		this.javaClass = clazz;
	}


	/**
	 * Adds the action.
	 *
	 * @param action the action
	 */
	public void addAction(AppAction action){
		action.setDeclaringModule(this);
		actions.put(action.getSignature(), action);
		String md5 = HashFunctions.getMD5(action.getSignature());
		action.setHash(md5);
		hashBindings.put(md5, action.getSignature());
	}

	/**
	 * Gets the action.
	 *
	 * @param signature the signature
	 *
	 * @return the action
	 */
	public AppAction getAction(String signature){
		return actions.get(signature);
	}

	public AppAction getActionByHash(String hash){
		return actions.get(hashBindings.get(hash));
	}

	public Collection<AppAction> getActions(){
		return actions.values();
	}

	public boolean containsActions(){
		return !actions.isEmpty();
	}


	public Object getJavaObject() {
		return javaObject;
	}

	public void setJavaObject(Object javaObject) {
		this.javaObject = javaObject;
	}


	public void validateActions() {
		Enumeration<AppAction> elements = actions.elements();
		while(elements.hasMoreElements()){
			AppAction action = elements.nextElement();
			Method scannedMethod = action.getJavaMethod();
			Method realMethod = null;
			try {
				realMethod = javaObject.getClass().getDeclaredMethod(scannedMethod.getName(), scannedMethod.getParameterTypes());
			} catch (SecurityException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (NoSuchMethodException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			if((!scannedMethod.equals(realMethod))&&(realMethod!=null)){
				action.setJavaMethod(realMethod);
			}
		}
	}

	public String getHash() {
		return hash;
	}

	public void setHash(String hash) {
		this.hash = hash;
	}
}
